package com.demdevdudes.disch.helpers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.demdevdudes.disch.commons.BaseAttributes;
import com.demdevdudes.disch.gameobjects.AbstractGameObject;

public class SpriteText extends AbstractGameObject {

	private static Map<String, Sprite> characterSprites = null;
	private List<Sprite> wordSprites = null;

	//FIXME we don't need to hold the text as a variable
	//because we generate a collection of sprites and never
	//use it again. for further explanation have a look at
	//the comment concerning the method 'render'
	private String text;
	private float offset;
	private float size;

	/**
	 * @param text The text to generate
	 * @param size Letter size
	 * @param x horizontal position
	 * @param y vertical position
	 */
	public SpriteText(String text, float size, float x, float y) {
		super(x, y);
		
		this.text = text;
		this.offset = BaseAttributes.TEXT_DEFAULT_OFFSET;
		this.size = size;

		// load all character sprites once
		if (characterSprites == null) {
			characterSprites = new HashMap<String, Sprite>();
			loadStringSprites();
			//FIXME may we should move the map of sprites to a
			//new class AssetLoader where all Sprites for the game
			//get gathered
			//furthermore textures have to be disposed to free
			//the memory after usage (have a look at the AssetLoader
			//of the ZombieBird project)
		}
	}

	private void loadStringSprites() {
		Texture t = null;
		
		for (char c : "abcdefghijklmnopqrstuvwxyz".toCharArray()) {
			t = new Texture(Gdx.files.internal("data/letters/" + c + ".png"));
			t.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
			characterSprites.put(String.valueOf(c), new Sprite(t));
		}
	}

	private void createText(String text) {
		wordSprites = new ArrayList<Sprite>();

		int count = 0;
		Sprite s = null;
		float currentX = getCoords2dVector().x;
		
		for (char c : text.toCharArray()) {
			s = characterSprites.get(String.valueOf(c));
			s.setX(currentX + offset * count++);
			s.setY(getCoords2dVector().y);
			s.setSize(size, size);
			currentX += size;
			wordSprites.add(s);
		}
	}

	public void render(SpriteBatch batch) {
		//FIXME creating the text every time the render
		//method is called is extremely ineffective because
		//it will usually be called multiple times a second
		//while the text doesn't even change. this will result
		//in a lot of ArrayList objects within the memory and
		//unnecessary garbage collection
		
		createText(text);
		
		for (Sprite s : wordSprites) {
			s.setAlpha(getAlpha());
			s.draw(batch);
		}
	}

	public String getText() {
		return this.text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public void setOffset(float offset) {
		this.offset = offset;
	}

	public float getOffset() {
		return this.offset;
	}

	public void setCharacterSize(float size) {
		this.size = size;
	}
}
